package com.moji.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.moji.common.base.ApiResult;
import com.moji.common.entity.MyPage;
import com.moji.common.utils.PageUtil;
import com.moji.entity.RoleMenuRel;
import com.moji.entity.SysMenu;
import com.moji.entity.dto.PrOnOffDto;
import com.moji.entity.dto.QuerySysMenuDto;
import com.moji.entity.dto.TreeMenuDto;
import com.moji.enums.MoJiEnumConfig;
import com.moji.mapper.RoleMenuRelMapper;
import com.moji.mapper.SysMenuMapper;
import com.moji.service.SysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moji.util.MenuTreeUtil;
import com.moji.util.MoJiCommonUtils;
import com.moji.util.ResultCode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author ccl
 * @since 2024-07-23
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Resource
    private RoleMenuRelMapper roleMenuRelMapper;

    @Override
    public ApiResult add(SysMenu sysMenu) {
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
        //校验权限字符不为空时，不能重复
        if(StringUtils.isNotEmpty(sysMenu.getPermissionCharacter())){
            wrapper.eq(SysMenu::getPermissionCharacter,sysMenu.getPermissionCharacter());
            SysMenu ccpSystemMenu0 = this.getOne(wrapper);
            if(ccpSystemMenu0 != null){
                throw new RuntimeException("权限字符数据已存在,请核查!");
            }
        }
        //校验路由名称不为空时，不能重复
        if(StringUtils.isNotEmpty(sysMenu.getRouteName())){
            wrapper.eq(SysMenu::getRouteName,sysMenu.getRouteName())
                    .eq(SysMenu::getMenuFlag,MoJiEnumConfig.CCP_SYSTEM_SHI.getCode());
            SysMenu ccpSystemMenu1 = this.getOne(wrapper);
            if(ccpSystemMenu1 != null){
                throw new RuntimeException("路由名称不能重复,请核查!");
            }
        }
        //校验菜单编码不重复
        if(StringUtils.isEmpty(sysMenu.getParentCode()) && StringUtils.isEmpty(sysMenu.getMenuRoute())){
            wrapper.eq(SysMenu::getMenuRoute,sysMenu.getMenuRoute())
                    .eq(SysMenu::getParentCode,sysMenu.getParentCode())
                    .eq(SysMenu::getMenuFlag,MoJiEnumConfig.CCP_SYSTEM_SHI.getCode());
            SysMenu ccpSystemMenu0 = this.getOne(wrapper);
            if(ccpSystemMenu0 != null){
                throw new RuntimeException("菜单路由已存在,请核查!");
            }
        }

        //如果上级菜单为空，默认一级菜单
        if(StringUtils.isEmpty(sysMenu.getParentCode())){
            sysMenu.setMenuCode("0000");
            sysMenu.setMenuName("moji");
            sysMenu.setParentCode("0");
            sysMenu.setParentName("0");
            sysMenu.setUrl("/moji");
            sysMenu.setMenuPath("moji");
            if(sysMenu.getSort() == null) {
                sysMenu.setSort(1);
            }
            sysMenu.setLevels(1);
        }else{
            //父级
            SysMenu ccpSystemMenu0 = this.getOne(new LambdaQueryWrapper<SysMenu>()
                    .eq(SysMenu::getParentCode,sysMenu.getParentCode())
                            .eq(SysMenu::getMenuFlag,MoJiEnumConfig.CCP_SYSTEM_SHI.getCode()));

            //同级兄弟
            wrapper.eq(SysMenu::getParentCode,sysMenu.getParentCode());
            wrapper.orderByDesc(SysMenu::getSort);
            List<SysMenu> ccpSystemMenuList = this.list(wrapper);
            if (ccpSystemMenuList.isEmpty()) {//不存在同级
                sysMenu.setSort(1);
                sysMenu.setLevels(1);
                sysMenu.setMenuCode(ccpSystemMenu0.getMenuCode()+String.format("%02d", 1));
                if(MoJiEnumConfig.CCP_SYSTEM_SHI.getCode().equals(sysMenu.getMenuFlag())){
                    sysMenu.setMenuPath(ccpSystemMenu0.getMenuPath()+"," + sysMenu.getMenuRoute());
                    sysMenu.setUrl(ccpSystemMenu0.getUrl()+"/" + sysMenu.getMenuRoute());
                }else{
                    sysMenu.setMenuPath(sysMenu.getPermissionCharacter());
                    sysMenu.setUrl(sysMenu.getPermissionCharacter());
                }
            }else{//存在同级
                if(sysMenu.getSort() == null) {
                    sysMenu.setSort(ccpSystemMenuList.get(0).getSort()+1);
                }
                sysMenu.setLevels(ccpSystemMenuList.get(0).getLevels());
                sysMenu.setMenuCode(Long.parseLong(ccpSystemMenuList.get(0).getMenuCode())+1+"");
                if(MoJiEnumConfig.CCP_SYSTEM_SHI.getCode().equals(sysMenu.getMenuFlag())){
                    sysMenu.setMenuPath(ccpSystemMenu0.getMenuPath()+"," + sysMenu.getMenuRoute());
                    sysMenu.setUrl(ccpSystemMenu0.getUrl()+"/" + sysMenu.getMenuRoute());
                }else{
                    sysMenu.setMenuPath(sysMenu.getPermissionCharacter());
                    sysMenu.setUrl(sysMenu.getPermissionCharacter());
                }
            }
        }
        sysMenu.setSystemCode(MoJiEnumConfig.TGW_SYSTEM_PLATFORM_CODE.getCode());
        sysMenu.setSystemName(MoJiEnumConfig.TGW_SYSTEM_PLATFORM_CODE.getMessage());
        sysMenu.setPrOnoff(sysMenu.getPrOnoff());
        sysMenu.setCreateTime(new Date());
        sysMenu.setUpdateTime(new Date());
        sysMenu.setOperatorId(MoJiCommonUtils.getUserCode());
        sysMenu.setCreateId(MoJiCommonUtils.getUserCode());

        return ApiResult.ok(this.save(sysMenu));
    }

    @Override
    public ApiResult edit(SysMenu sysMenu) {
        SysMenu ccpSystemMenuOld = this.getById(sysMenu.getId());
        //校验权限字符不为空时，不能重复
        if(StringUtils.isNotEmpty(sysMenu.getPermissionCharacter())){
            if(!ccpSystemMenuOld.getPermissionCharacter().equals(sysMenu.getPermissionCharacter())){
                LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(SysMenu::getPermissionCharacter,sysMenu.getPermissionCharacter());
                SysMenu ccpSystemMenu0 = this.getOne(wrapper);
                if(ccpSystemMenu0 != null){
                    throw new RuntimeException("权限字符数据已存在,请核查!");
                }
            }
        }
        //校验菜单编码不重复
        if(StringUtils.isEmpty(sysMenu.getParentCode()) && StringUtils.isEmpty(sysMenu.getMenuCode())){
            if(!ccpSystemMenuOld.getMenuRoute().equals(sysMenu.getMenuRoute())){
                LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(SysMenu::getMenuRoute,sysMenu.getMenuRoute())
                        .eq(SysMenu::getParentCode,sysMenu.getParentCode())
                        .eq(SysMenu::getMenuFlag,MoJiEnumConfig.CCP_SYSTEM_SHI.getCode());
                SysMenu ccpSystemMenu0 = this.getOne(wrapper);
                if(ccpSystemMenu0 != null){
                    throw new RuntimeException("菜单编码已存在,请核查!");
                }
            }
        }
        sysMenu.setUpdateTime(new Date());
        sysMenu.setOperatorId(MoJiCommonUtils.getUserCode());
        //菜单：url重新设值
        if(MoJiEnumConfig.CCP_SYSTEM_SHI.getCode().equals(sysMenu.getMenuFlag())){
            String newUrl=ccpSystemMenuOld.getUrl().substring(0,ccpSystemMenuOld.getUrl().lastIndexOf("/")+1);
            String newPath=ccpSystemMenuOld.getMenuPath().substring(0,ccpSystemMenuOld.getMenuPath().lastIndexOf(",")+1);
            sysMenu.setUrl(newUrl+sysMenu.getMenuRoute());
            sysMenu.setMenuPath(newPath+sysMenu.getMenuRoute());
        }else{//按钮
            sysMenu.setUrl(sysMenu.getPermissionCharacter());
            sysMenu.setMenuPath(sysMenu.getPermissionCharacter());
        }

        boolean bol=this.updateById(sysMenu);

        //分配过权限的数据表，同步修改
        LambdaQueryWrapper<RoleMenuRel> relWrapper = new LambdaQueryWrapper<>();
        relWrapper.eq(RoleMenuRel::getMenuCode,sysMenu.getMenuCode())
                .eq(RoleMenuRel::getUrl,sysMenu.getUrl());

        List<RoleMenuRel> roleMenuRels = roleMenuRelMapper.selectList(relWrapper);
        for (RoleMenuRel roleMenuRel : roleMenuRels) {
            roleMenuRel.setMenuName(sysMenu.getMenuName());
            roleMenuRelMapper.updateById(roleMenuRel);
        }
        return ApiResult.ok(bol);
    }

    @Override
    public ApiResult delete(Long systemMenuId) {
        //原菜单
        SysMenu sysMenu = this.getById(systemMenuId);
        if (sysMenu == null) {
            return ApiResult.failed("菜单不存在,请核查！");
        }
        //子菜单
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysMenu::getParentCode,systemMenuId)
                .eq(SysMenu::getSystemCode,sysMenu.getSystemCode());
        List<SysMenu> menuList2 = this.list(wrapper);
        if (!menuList2.isEmpty()) {
            return ApiResult.failed("存在子菜单，不能删除此菜单！");
        }
        //启用状态不能删除
        if (MoJiEnumConfig.CCP_SYSTEM_PR_ON_ON.getCode().equals(sysMenu.getPrOnoff().toString())) {
            return ApiResult.failed(ResultCode.PLATFORM_ON_NOT_DELETE.getMsg());
        } else {
            //一级菜单不能删除
            if ("0".equals(sysMenu.getParentCode())) {
                return ApiResult.failed(ResultCode.TOP_MENU_NOT_DELETE.getMsg());
            } else {
                //删除本菜单及其子菜单
                this.removeById(systemMenuId);
                this.remove(wrapper);
                //分配过权限的数据表，同步删除
                LambdaQueryWrapper<RoleMenuRel> relWrapper = new LambdaQueryWrapper<>();
                relWrapper.eq(RoleMenuRel::getMenuCode,sysMenu.getId())
                        .eq(RoleMenuRel::getUrl,sysMenu.getUrl());
                return ApiResult.ok(roleMenuRelMapper.delete(relWrapper));
            }
        }
    }

    @Override
    public MyPage<SysMenu> queryPage(QuerySysMenuDto dto) {
        LambdaQueryWrapper<SysMenu> ccpSystemMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(dto.getPlatformNumber())) {
            ccpSystemMenuLambdaQueryWrapper.eq(SysMenu::getSystemCode,dto.getPlatformNumber());
        }
        if (!StringUtils.isEmpty(dto.getMenuName())) {
            ccpSystemMenuLambdaQueryWrapper.like(SysMenu::getMenuName,dto.getMenuName());
        }
        if (!StringUtils.isEmpty(dto.getMenuCode())) {
            ccpSystemMenuLambdaQueryWrapper.like(SysMenu::getMenuCode,dto.getMenuCode());
        }
        ccpSystemMenuLambdaQueryWrapper.orderByDesc(SysMenu::getUpdateTime);
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        List<SysMenu> menuList = this.list(ccpSystemMenuLambdaQueryWrapper);
        PageInfo<SysMenu> info = new PageInfo<>(menuList);
        return PageUtil.PageInfo2MyPage(info);
    }

    @Override
    public List<TreeMenuDto> queryMenuTree(QuerySysMenuDto dto) {
        LambdaQueryWrapper<SysMenu> ccpSystemMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(dto.getPlatformNumber())) {
            ccpSystemMenuLambdaQueryWrapper.eq(SysMenu::getSystemCode,dto.getPlatformNumber());
        } else {
            ccpSystemMenuLambdaQueryWrapper.eq(SysMenu::getSystemCode,MoJiEnumConfig.CCP_SYSTEM_PR_ON_ON.getCode());
        }
        if (!StringUtils.isEmpty(dto.getMenuName())) {
            ccpSystemMenuLambdaQueryWrapper.like(SysMenu::getMenuName,dto.getMenuName());
        }
        if (!StringUtils.isEmpty(dto.getMenuCode())) {
            ccpSystemMenuLambdaQueryWrapper.like(SysMenu::getMenuCode,dto.getMenuCode());
        }
        ccpSystemMenuLambdaQueryWrapper.eq(SysMenu::getPrOnoff,1);
        ccpSystemMenuLambdaQueryWrapper.orderByAsc(SysMenu::getSort);
        List<SysMenu> menuList = this.list(ccpSystemMenuLambdaQueryWrapper);
        if (!StringUtils.isEmpty(dto.getMenuName()) || !StringUtils.isEmpty(dto.getMenuCode())) {
            return MenuTreeUtil.list2TreeList(menuList);
        }
        return MenuTreeUtil.list2Tree(menuList);
    }

    @Override
    public Boolean updateMenuStatus(PrOnOffDto prOnOffDao) {
        SysMenu sysMenu = this.getById(prOnOffDao.getId());
        if (sysMenu != null) {
            sysMenu.setPrOnoff(Integer.parseInt(prOnOffDao.getPrOnOff()));
            sysMenu.setPrOnoffTime(new Date());
        }
        return this.updateById(sysMenu);
    }

    @Override
    public List<TreeMenuDto> queryAllMenuTree(QuerySysMenuDto dto) {
        LambdaQueryWrapper<SysMenu> ccpSystemMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(dto.getPlatformNumber())) {
            ccpSystemMenuLambdaQueryWrapper.eq(SysMenu::getSystemCode,dto.getPlatformNumber());
        } else {
            ccpSystemMenuLambdaQueryWrapper.eq(SysMenu::getSystemCode,MoJiEnumConfig.CCP_SYSTEM_PR_ON_ON.getCode());
        }
        if (!StringUtils.isEmpty(dto.getMenuName())) {
            ccpSystemMenuLambdaQueryWrapper.like(SysMenu::getMenuName,dto.getMenuName());
        }
        if (!StringUtils.isEmpty(dto.getMenuCode())) {
            ccpSystemMenuLambdaQueryWrapper.like(SysMenu::getMenuCode,dto.getMenuCode());
        }
        ccpSystemMenuLambdaQueryWrapper.orderByAsc(SysMenu::getSort);
        List<SysMenu> menuList = this.list(ccpSystemMenuLambdaQueryWrapper);
        if (!StringUtils.isEmpty(dto.getMenuName()) || !StringUtils.isEmpty(dto.getMenuCode())) {
            return MenuTreeUtil.list2TreeList(menuList);
        }
        return MenuTreeUtil.list2Tree(menuList);
    }
}
